package ZorkXMLParser;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Stack;

public class ZorkXMLHandler extends DefaultHandler
{
    private Stack pastMaps;
    private Stack pastKeys;
    private HashMap lastMap;
    private HashMap currentMap;
    private boolean justStarted;
    private ArrayList list;

    private static final HashMap emptyMap = new HashMap();
    
    public ZorkXMLHandler()
    {
        super();
        pastMaps = new Stack();
        pastKeys = new Stack();
        currentMap = new HashMap();
        justStarted = false;
    }

    public void startElement(String uri, String localName, 
                             String qName, Attributes attributes) throws SAXException
    {
        qName = qName.toLowerCase();
        lastMap = currentMap;
        pastMaps.push(currentMap);
        currentMap = new HashMap();

        if(lastMap.get(qName) == null) {
            lastMap.put(qName, currentMap);
        }
        else if(lastMap.get(qName) instanceof ArrayList)
        {
            list = (ArrayList)lastMap.get(qName);
            list.add(currentMap);
        }
        else 
        {
            list = new ArrayList();
            list.add(currentMap);
            list.add(lastMap.get(qName));
            lastMap.put(qName, list);
        }

        pastKeys.push(qName);
        justStarted = false;
    }

    public void endElement(String uri, String localName, String qName) throws SAXException
    {
        qName = qName.toLowerCase();
        if(!justStarted) {
            currentMap = (HashMap)pastMaps.pop();
        }
        pastKeys.pop();
        justStarted = false;
    }

    public void characters(char ch[], int start, int length) throws SAXException
    {
        String elementString = new String(ch, start, length).trim();

        if(elementString.length() > 0)
         {
            currentMap = (HashMap)pastMaps.pop(); 
            Object o = currentMap.get(pastKeys.peek());

            if(o instanceof ArrayList) 
            {
                list = (ArrayList)o;
                list.add(elementString);
                while(list.contains(emptyMap)) {
                    list.remove(emptyMap);
                }
                currentMap.put(pastKeys.peek(), list);
            }
            else {
                currentMap.put(pastKeys.peek(), elementString);
            }

            justStarted = true;
        }
    }

    public HashMap getMap()
    {
        return currentMap;
    }
}

